﻿namespace SomethingSpacial.LoginUI
{
    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Linq;
    using System.Reflection;
    using System.Windows;
    using System.Windows.Automation.Peers;
    using System.Windows.Automation.Provider;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.ServiceModel.DomainServices.Client.ApplicationServices;
    using SomethingSpacialClassLib.Web;
    using SomethingSpacial.AppServices.Resources;
    using SomethingSpacial.AppServices;
    using SomethingSpacial.AppServices.Web;
    using System.Windows.Media.Animation;
    using System.Windows.Shapes;
    using System.Windows.Media.Imaging;
    using System.Windows.Media;
    using System.IO;
    using System.Windows.Browser;
    using Silverlight.Samples;
    using Liquid;
    using Liquid.Components;
    using System.ServiceModel.DomainServices.Client;

    public partial class RegistrationFormPretty : StackPanel
    {
        private RegistrationData registrationData = new RegistrationData();
       // private UserRegistrationContext userRegistrationContext = new UserRegistrationContext();
        private LoginRegistrationWindow parentWindow;
        private AppServices.Web.UserRegistrationContext appUserRegistrationContext = new AppServices.Web.UserRegistrationContext();

        private CaptureSource CapSrc = new CaptureSource();
        private VideoBrush MyVideoBrush = new VideoBrush();
        private WriteableBitmap _bitmap;
        private bool VideoIsPlaying = false;
        //string WebServicePath = HtmlPage.Document.DocumentUri;
        //  Uri uri = new Uri(HtmlPage.Document.DocumentUri, "FileUploadService.asmx");
        private Uploader _uploader = new Uploader(new Uri(HtmlPage.Document.DocumentUri, "FileUploadService.asmx").ToString());

        public RegistrationFormPretty()
        {
            InitializeComponent();

          //  this.appUserRegistrationContext.RegistrationDatas.Add(this.   registrationData);
            this.Loaded += new RoutedEventHandler(RegistrationFormPretty_Loaded);
            //this.registerForm.CurrentItem = this.registrationData;
            //this.registerForm.AutoGeneratingField += this.RegisterForm_AutoGeneratingField;
        }

        void RegistrationFormPretty_Loaded(object sender, RoutedEventArgs e)
        {
            StartCamBtn.Click += new RoutedEventHandler(StartCamBtn_Click);
            TakeSnapBtn.Click += new RoutedEventHandler(TakeSnapBtn_Click);
            SaveSnapBtn.Click += new RoutedEventHandler(SaveSnapBtn_Click);
            DataBindSecurityQuestions();
            textBoxUserName.LostFocus += new RoutedEventHandler(textBoxUserName_LostFocus);
            _uploader.UploadProgressChange += new UploadEventHandler(Uploader_UploadProgressChange);
            _uploader.UploadFinished += new UploadEventHandler(Uploader_UploadFinished);




        }

        private void Uploader_UploadFinished(object sender, UploadEventArgs e) 
        { 
            progress.Text = "Complete."; 
            progress.Complete = e.Progress; 
        }

        private void Uploader_UploadProgressChange(object sender, UploadEventArgs e) 
        { 
            progress.Text = "Uploading " + Math.Round(e.Progress) + "% (" + e.Text + ")"; 
            progress.Complete = e.Progress; 
        }


        void textBoxUserName_LostFocus(object sender, RoutedEventArgs e)
        {
            if (textBoxFriendlyName.Text.Trim().Length == 0)
            {
                textBoxFriendlyName.Text = textBoxUserName.Text;
            }
        }

        /// <remarks>
        ///     <see cref="LoginRegistrationWindow"/> will call this setter
        ///     during its initialization
        /// </remarks>
        public void SetParentWindow(LoginRegistrationWindow window)
        {
            this.parentWindow = window;
        }

        /// <summary>
        ///     Adds some additional behaviors to some of the DataForm's fields
        /// </summary>
        private void RegisterForm_AutoGeneratingField(object dataForm, DataFormAutoGeneratingFieldEventArgs e)
        {
            if (e.PropertyName == "Password")
            {
                PasswordBox passwordBox = (PasswordBox)e.Field.Content;

                passwordBox.PasswordChanged += (sender, eventArgs) =>
                {
                    // If the password is invalid, the entity property doesn't get updated.
                    // Thus, we keep a separate password copy (the ActualPassword property)
                    // that is guaranteed to match what the user typed
                    //((RegistrationData)this.registerForm.CurrentItem).ActualPassword = ((PasswordBox)sender).Password;
                };

                passwordBox.LostFocus += (sender, eventArgs) =>
                {
                    // Prevent this from having any effect after a submission
                    if (this.registrationData.EntityState == EntityState.Unmodified)
                    {
                        return;
                    }

                    // If there is something typed on the password confirmation box
                    // then we need to re-validate it
                   // if (!String.IsNullOrEmpty(((PasswordBox)this.registerForm.Fields["PasswordConfirmation"].Content).Password))
                    //{
                      //  this.registerForm.Fields["PasswordConfirmation"].Validate();
                   // }
                };
            }
            else if (e.PropertyName == "UserName")
            {
                // Auto-fill FriendlyName if there is not already something in there
                TextBox userNameTextBox = (TextBox)e.Field.Content;

                userNameTextBox.LostFocus += (sender, eventArgs) =>
                {
                    //TextBox friendlyNameTextBox = (TextBox)this.registerForm.Fields["FriendlyName"].Content;

                    //if (string.IsNullOrEmpty(friendlyNameTextBox.Text))
                   // {
                   //     friendlyNameTextBox.Text = userNameTextBox.Text;
                   // }
                };
            }
        }


        private void  DataBindSecurityQuestions()
        {
            // Use reflection to grab all the localized security questions
            IEnumerable<string> availableQuestions = from propertyInfo in typeof(SecurityQuestions).GetProperties()
                                                     where propertyInfo.PropertyType.Equals(typeof(string))
                                                     select (string)propertyInfo.GetValue(null, null);

            dropDownSecurityAnswer.ItemsSource = availableQuestions;
        }


        /// <summary>
        ///     If form is valid, submits userRegistrationContext information to the server
        /// </summary>
        private void RegisterButton_Click(object sender, RoutedEventArgs e)
        {
         //   if (this.registerForm.ValidateItem() && this.registerForm.CommitEdit())
            
            {
                SubmitOperation regOp = appUserRegistrationContext.SubmitChanges(this.RegistrationOperation_Completed, null);
                this.BindUIToOperation(regOp);
                this.parentWindow.AddPendingOperation(regOp);
            }
        }

        /// <summary>
        ///     Handles <see cref="SubmitOperation.Completed"/> for a userRegistrationContext
        ///     operation. If there was an error, an <see cref="ErrorWindow"/> is
        ///     displayed to the user. Otherwise, this triggers a <see cref="LoginOperation"/>
        ///     that will automatically log in the just registered user
        /// </summary>
        private void RegistrationOperation_Completed(SubmitOperation asyncResult)
        {
            if (asyncResult.HasError)
            {
                ErrorWindow.CreateNew(asyncResult.Error);
                asyncResult.MarkErrorAsHandled();
                this.saveStatus.Text = "setting saved";
            }
            else
            {
                LoginOperation loginOperation = AppServices.WebContext.Current.Authentication.Login(appUserRegistrationContext.RegistrationDatas.First().ToLoginParameters(), this.LoginOperation_Completed, null);
                this.BindUIToOperation(loginOperation);
                this.parentWindow.AddPendingOperation(loginOperation);
            }
        }

        /// <summary>
        ///     Binds UI so that controls will look disabled and activity will be
        ///     displayed while operation is in progress. For simplicity Cancel button 
        ///     will be disabled during the operation even if it is cancellable
        /// </summary>
        /// <param name="operation"></param>
        private void BindUIToOperation(OperationBase operation)
        {
            Binding isActivityActiveBinding = operation.CreateOneWayBinding("IsComplete", new NotOperatorValueConverter());
            Binding isEnabledBinding = operation.CreateOneWayBinding("IsComplete");

            //this.activity.SetBinding(Activity.IsActiveProperty, isActivityActiveBinding);
            //this.registerForm.SetBinding(Control.IsEnabledProperty, isEnabledBinding);
            this.registerButton.SetBinding(Control.IsEnabledProperty, isEnabledBinding);
            this.registerCancel.SetBinding(Control.IsEnabledProperty, isEnabledBinding);
            this.backToLogin.SetBinding(Control.IsEnabledProperty, isEnabledBinding);
        }

        /// <summary>
        ///     Handles <see cref="LoginOperation.Completed"/> event for
        ///     the login operation that is sent right after a successful
        ///     userRegistrationContext. This will close the window. On the unexpected
        ///     event that this operation failed (the user was just added so
        ///     why wouldn't it be authenticated successfully) an 
        ///     <see cref="ErrorWindow"/> is created and will display the
        ///     error message.
        /// </summary>
        /// <param name="loginOperation"></param>
        private void LoginOperation_Completed(LoginOperation loginOperation)
        {
            this.parentWindow.Close();

            if (loginOperation.HasError)
            {
                ErrorWindow.CreateNew(string.Format(System.Globalization.CultureInfo.CurrentUICulture, ApplicationStrings.ErrorLoginAfterRegistrationFailed, loginOperation.Error.Message));
                loginOperation.MarkErrorAsHandled();
            }
            else if (loginOperation.LoginSuccess == false)
            {
                // ApplicationStrings.ErrorBadUserNameOrPassword is the correct error message as operation succeeded but login failed
                ErrorWindow.CreateNew(string.Format(System.Globalization.CultureInfo.CurrentUICulture, ApplicationStrings.ErrorLoginAfterRegistrationFailed, ApplicationStrings.ErrorBadUserNameOrPassword));
            }
        }

        private void BackToLogin_Click(object sender, RoutedEventArgs e)
        {
            this.parentWindow.NavigateToLogin();
        }

        private void CancelButton_Click(object sender, RoutedEventArgs e)
        {
            this.parentWindow.Close();
        }

        private void SaveButton_Click(object sender, RoutedEventArgs e)
        {



            RegistrationData newUser = new RegistrationData();

                newUser.UserName = textBoxUserName.Text;
                newUser.Password = textBoxPassword.Password;
                newUser.ActualPassword = newUser.Password;
                newUser.PasswordConfirmation = textBoxConfirmPassword.Password;
                newUser.Email = textBoxEmail.Text;
                newUser.Question = dropDownSecurityAnswer.SelectedValue.ToString();
                newUser.Answer = textBoxSecurityAnswer.Text;
                


                //Update User Profile Values
                newUser.Address = textBoxAddress.Text;
                newUser.Bio = textBoxBio.Text;
                newUser.City = textBoxCity.Text;
                newUser.FacebookID = textBoxFacebookID.Text;
                newUser.FriendlyName = textBoxFriendlyName.Text;
                newUser.LinkedInID = textBoxLinkedInID.Text;
                newUser.PhotoUrl = "";
                newUser.State = "FL"; // dropDownState.SelectedValue.ToString();
                newUser.TwitterID = textBoxTwitterID.Text;
                newUser.ZipCode = textBoxZip.Text;
            


                appUserRegistrationContext.RegistrationDatas.Add(newUser);
                SubmitOperation regOp = appUserRegistrationContext.SubmitChanges(this.RegistrationOperation_Completed, null);
                this.BindUIToOperation(regOp);
                this.parentWindow.AddPendingOperation(regOp);

                this.saveStatus.Text = "setting saving..";


        }

        void SaveSnapBtn_Click(object sender, RoutedEventArgs e)
        {
            SaveTheImg();
        }

        void TakeSnapBtn_Click(object sender, RoutedEventArgs e)
        {
            WriteableBitmap snapShot = new WriteableBitmap(SnapContainer, null);
            Image image = new Image();
            image.Width = 400;
            image.Source = snapShot;
            if (ImgHolder.Children.Count == 1)
            {
                ImgHolder.Children.RemoveAt(0);
            }
            ImgHolder.Children.Add(image);

        }

        void StartCamBtn_Click(object sender, RoutedEventArgs e)
        {
            if (!VideoIsPlaying)
            {
                VideoIsPlaying = true;
                if (CaptureDeviceConfiguration.AllowedDeviceAccess || CaptureDeviceConfiguration.RequestDeviceAccess())
                {
                    MyVideoBrush.SetSource(CapSrc);
                    WebcamCanvas.Fill = MyVideoBrush;
                    CapSrc.Start();
                }
            }
            else
            {
                VideoIsPlaying = false;
                CapSrc.Stop();
            }

        }

        private void SaveTheImg()
        {
            _bitmap = new WriteableBitmap(ImgHolder, null);
            SaveFileDialog sfd = new SaveFileDialog();
            sfd.Filter = "PNG Files (*.png)|*.png|All Files (*.*)|*.*";
            sfd.DefaultExt = ".png";
            sfd.FilterIndex = 1;




            //OpenFileDialog ofd = new OpenFileDialog();
            /*
            sfd.Filter = "PNG Files (*.png)|*.png|All Files (*.*)|*.*";
            sfd.DefaultExt = ".png";
            sfd.FilterIndex = 1;

            OpenFileDialog dialog = new OpenFileDialog();

            dialog.Filter = "Image files (*.gif;*.jpg;*.png)|*.gif;*.jpg;*.png";
            dialog.Multiselect = false;

            */

            if ((bool)sfd.ShowDialog())
            {
                using (Stream fs = sfd.OpenFile())
                {
                    textBlockFileName.Text = sfd.SafeFileName;
                    int width = _bitmap.PixelWidth;
                    int height = _bitmap.PixelHeight;

                    EditableImage ei = new EditableImage(width, height);

                    for (int i = 0; i < height; i++)
                    {
                        for (int j = 0; j < width; j++)
                        {
                            int pixel = _bitmap.Pixels[(i * width) + j];
                            ei.SetPixel(j, i,
                                        (byte)((pixel >> 16) & 0xFF),
                                        (byte)((pixel >> 8) & 0xFF),
                                        (byte)(pixel & 0xFF),
                                        (byte)((pixel >> 24) & 0xFF)
                            );
                        }
                    }
                    Stream png = ei.GetStream();
                    int len = (int)png.Length;
                    byte[] bytes = new byte[len];
                    png.Read(bytes, 0, len);
                    fs.Write(bytes, 0, len);

               //     _uploader.UploadFile("myUpload1", sfd.OpenFile, "documents/", true, "");
                }
            }
        }

        private void StartUpload_Click(object sender, RoutedEventArgs e)
        {
       //   FileInfo currFile = new FileInfo("C:\\David\\websites\\SilverlightUGStarterKit\\SomethingSpacial\\SomethingSpacial\\Images\\Logo.png");


          OpenFileDialog dialog = new OpenFileDialog();

          dialog.Filter = "Image files (*.gif;*.jpg;*.png)|*.gif;*.jpg;*.png";
          dialog.Multiselect = false;

          if (dialog.ShowDialog() == true)
          {
              _uploader.UploadFile("myUpload1", dialog.File, "Documents/", true, "");

          }

            //_uploader.UploadFiles("myUpload1", AllFiles, "documents/", true, "");
            //_uploader.UploadFile("myUpload1", currFile, "documents/", true, "");
        }



    }
}
